#include <memory>
#include "TcpServer.hpp"
#include "Protocol.hpp"
#include "Calculator.hpp"
#include "Daemon.hpp"

using cal_func = std::function<Response(Request& req)>;

class Parse
{
public:
    Parse(cal_func cal)
        : _cal(cal)
    {}
    std::string Entry(std::string &package)
    {
        // 1.判断报文完整性
        std::string message;
        std::string respstr;
        while (Decode(package, &message))
        {
            LOG(LogLevel::DEBUG) << "Content：\n" << message;

            if (message.empty())
                break;

            // 2.反序列化，message是一个曾经被序列化的Request对象
            Request req;
            std::cout << "###########################" << std::endl;
            req.Print();
            if (!req.Deserialize(message))
                break;

            // 3.进行计算
            Response resp = _cal(req);

            // 4.序列化，resp是一个Response对象
            std::string res;
            resp.Serialize(res);

            LOG(LogLevel::DEBUG) << "序列化：\n" << res;

            // 5.添加长度报头字段
            Encode(res);

            LOG(LogLevel::DEBUG) << "Encode：\n" << res;

            // 6.返回报文
            respstr += res;
        }
        LOG(LogLevel::DEBUG) << "resptr：\n" << respstr;
        return respstr;
    }
private:
    cal_func _cal;
};

int main()
{
    // ENABLE_CONSOLE_LOG();
    ENABLE_FILE_LOG();

    Daemon(false, false); // 设置守护进程

    // 1. 计算模块
    Calculator mycal;

    // 2. 解析模块
    Parse myparse([&mycal](Request& req){   
        return mycal.Execute(req);
    });

    // 3. 服务器模块
    std::unique_ptr<TcpServer> tsvr = std::make_unique<TcpServer>([&myparse](std::string &package) {
        return myparse.Entry(package); 
    });

    tsvr->InitServer();
    tsvr->Start();

    return 0;
}
